﻿using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Tiens.NotificationHub.Constant;
using Tiens.NotificationHub.Models;
using Tiens.NotificationHub.Services;

namespace Tiens.NotificationHub.Core
{
    public class InMemoryAppConnectionManager: IAppConnectionManager
    {
        private ConcurrentDictionary<string, AppConnection> _appConnections { get; set; }

        public InMemoryAppConnectionManager()
        {
            _appConnections = new ConcurrentDictionary<string, AppConnection>();
        }

        public Task JoinAsync(string userId, string appId, string connectionId)
        {
            var sessionApp = _appConnections.GetOrAdd(userId.ToGroupName(appId), new AppConnection(userId, appId));
            sessionApp.AddConnection(connectionId);

            return Task.CompletedTask;
        }

        public Task QuitAsync(string groupName, string appId, string connectionId)
        {
            if (_appConnections.TryGetValue(groupName, out AppConnection connection))
            {
                connection.RemoveConnection(connectionId);
            }

            return Task.CompletedTask;
        }

        public Task<IEnumerable<string>> GroupsByAppIdAsync(string appId)
        {
           var data =  _appConnections.Where(x => x.Value.AppId.Equals(appId) && x.Value.ConnectionIds.Any())
                .Select(x => x.Key);

           return Task.FromResult(data);
        }

        public Task<IEnumerable<string>> UsersOnline(string appId)
        {
            var count = _appConnections.Where(x => x.Value.AppId.Equals(appId) && x.Value.ConnectionIds.Any())
                .Select(x => x.Value.UserId);

            return Task.FromResult(count);
        }

        //在线数
        public Task<int> UsersOnlineNumber(string appId)
        {
           var count =  _appConnections.Count(x => x.Value.AppId.Equals(appId) && x.Value.ConnectionIds.Any());

           return Task.FromResult(count);
        }

        public Task<IEnumerable<string>> ConnectionIds(string appId)
        {
            var connectionIds =  _appConnections.Where(x => x.Value.AppId.Equals(appId)).SelectMany(x => x.Value.ConnectionIds);

            return Task.FromResult(connectionIds);
        }

        public Task<IEnumerable<string>> ConnectionIds(string userId, string appId)
        {
            var connectionIds = _appConnections.Where(x => x.Key.Equals(userId) && x.Value.AppId.Equals(appId))
                .SelectMany(x => x.Value.ConnectionIds);

            return Task.FromResult(connectionIds);
        }
            
    }

}
